package com.jtny.nytb.equipment.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;

import com.jtny.component.entity.PageData;
import com.jtny.component.entity.WebResponse;
import com.jtny.component.util.BeanUtils;
import com.jtny.nytb.equipment.vo.dataparam.LabelVO;
import com.jtny.nytb.equipment.vo.device.*;
import com.jtny.nytb.equipment.vo.excel.ExcelResultVO;
import com.jtny.nytb.equipment.vo.excel.ExportExcelEquipmentVO;
import com.jtny.nytb.equipment.vo.excel.utils.EasyExcelUtils;
import com.jtny.nytb.equipment.vo.excel.utils.ExcelSheetVO;
import com.jtny.nytb.equipment.constant.ResultConstant;
import com.jtny.nytb.equipment.enums.DataParamImportEnum;
import com.jtny.nytb.equipment.service.EquipmentInfoExtraService;
import com.jtny.nytb.equipment.service.ImportExcelService;
import com.jtny.nytb.equipment.utils.ExcelSheetUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author 智慧能源中心 - zx
 * @package com.jtny.nytb.equipment.controller
 * @fileName EquipmentInfoController.java
 * @createTime 2023年09月19日 22:41
 * @Copyright© 2023 jtny
 * 江投能源技术研究院 版权所有
 */
@RestController
@Api(value = "设备管理", tags = "设备管理")
@ApiSort(204005)
@RequestMapping("/equipment-info")
@AllArgsConstructor
public class EquipmentInfoController {

    private EquipmentInfoExtraService equipmentInfoExtraService;
    private ImportExcelService importExcelService;

    /**
     * 设备分页查询操作
     *
     * @param equipmentInfoQueryPageParamVO
     * @return
     */
    @ApiOperation("设备分页查询操作")
    @ApiImplicitParam(name = "equipmentInfoQueryPageParamVO", value = "设备分页查询VO对象", required = true, paramType = "query", dataType = "EquipmentInfoQueryPageParamVO")
    @ApiOperationSupport(order = 1)
    @PostMapping("/queryPage")
    @ResponseBody
    public WebResponse<PageData<EquipmentInfoVO>> queryPage(@RequestBody EquipmentInfoQueryPageParamVO equipmentInfoQueryPageParamVO) {
        PageData<EquipmentInfoVO> equipmentInfoVOPageData = equipmentInfoExtraService.queryPage(equipmentInfoQueryPageParamVO);
        return WebResponse.success(equipmentInfoVOPageData);
    }

    /**
     * 设备信息删除操作
     *
     * @param id
     * @return
     */
    @ApiOperation("设备信息删除操作")
    @ApiImplicitParam(name = "id", value = "设备id", required = true, paramType = "path")
    @ApiOperationSupport(order = 2)
    @GetMapping("/deleteEqu/{id}")
    @ResponseBody
    public WebResponse<?> deleteEqu(@PathVariable("id") Long id) {
        equipmentInfoExtraService.deleteEquipmentAll(id, Boolean.FALSE);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }

    /**
     * 设备参数信息删除操作
     *
     * @param id
     * @return
     */
    @ApiOperation("设备参数信息删除操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "设备id", required = true, paramType = "path"),
            @ApiImplicitParam(name = "deleteDataParam", value = "是否删除数据参数", required = true, paramType = "path")
    })
    @ApiOperationSupport(order = 6)
    @GetMapping("/delete-equipment-all/{deleteDataParam}/{id}")
    @ResponseBody
    public WebResponse<?> deleteEquipmentAll(@PathVariable("deleteDataParam") Boolean deleteDataParam, @PathVariable("id") Long id) {
        equipmentInfoExtraService.deleteEquipmentAll(id, deleteDataParam);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }


    /**
     * 通过设备id查询单个设备信息
     */
    @ApiOperation("设备信息详情操作")
    @ApiImplicitParam(name = "id", value = "设备id", required = true, paramType = "path")
    @ApiOperationSupport(order = 3)
    @GetMapping("/detailsEqu/{id}")
    @ResponseBody
    public WebResponse<?> detailsEqu(@PathVariable("id") Long id) {
        return WebResponse.success(equipmentInfoExtraService.detailsEqu(id));
    }

    /**
     * 设备参数分页查询操作
     *
     * @param equipmentInfoParamPageQueryVO
     * @return
     */
    @ApiOperation("设备参数分页查询操作")
    @ApiImplicitParam(name = "equipmentInfoParamPageQueryVO", value = "设备参数分页查询VO对象", required = true, paramType = "query", dataType = "EquipmentInfoParamPageQueryVO")
    @ApiOperationSupport(order = 4)
    @PostMapping("/queryPageParam")
    @ResponseBody
    public WebResponse<?> queryPageParam(@RequestBody EquipmentInfoParamPageQueryVO equipmentInfoParamPageQueryVO) {
        PageData<EquipmentInfoParamVO> equipmentModelParamVOPageData = equipmentInfoExtraService.queryPageParam(equipmentInfoParamPageQueryVO);
        return WebResponse.success(equipmentModelParamVOPageData);
    }


    /**
     * 设备参数信息添加操作
     *
     * @param equipmentInfoParamVO
     * @return
     */
    @ApiOperation("设备参数信息添加操作")
    @ApiImplicitParam(name = "equipmentInfoParamVO", value = "设备模型参数添加VO对象", required = true, paramType = "query", dataType = "EquipmentInfoParamVO")
    @ApiOperationSupport(order = 5)
    @PostMapping("/savaParam")
    @ResponseBody
    public WebResponse<?> savaParam(@RequestBody EquipmentInfoParamVO equipmentInfoParamVO) {
        equipmentInfoExtraService.savaParam(equipmentInfoParamVO);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }

    /**
     * 设备参数信息删除操作
     *
     * @param id
     * @return
     */
    @ApiOperation("设备参数信息删除操作")
    @ApiImplicitParam(name = "id", value = "设备参数id", required = true, paramType = "path")
    @ApiOperationSupport(order = 6)
    @GetMapping("/deleteEquParam/{id}")
    @ResponseBody
    public WebResponse<?> deleteEquParam(@PathVariable("id") Long id) {
        equipmentInfoExtraService.deleteEquParam(id);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }

    /**
     * 通过code查询单个设备信息
     *
     * @param code
     * @return
     */
    @ApiOperation("设备信息详情操作")
    @ApiImplicitParam(name = "code", value = "设备编号code", required = true, paramType = "path")
    @ApiOperationSupport(order = 7)
    @GetMapping("/detailsEquCode/{code}")
    @ResponseBody
    public WebResponse<EquipmentInfoVO> detailsEquCode(@PathVariable("code") String code) {
        EquipmentInfoVO equipmentInfoVO = equipmentInfoExtraService.detailsEquCode(code);
        return WebResponse.success(equipmentInfoVO);
    }

    /**
     * 设备发布/未发布
     *
     * @param id     编号
     * @param status 地位
     * @return {@link WebResponse}<{@link ?}>
     */
    @ApiOperation("设备发布/未发布")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "设备Id", required = true, paramType = "path"),
            @ApiImplicitParam(name = "status", value = "设备状态 发布：0/未发布：1", required = true, paramType = "path"),
    })
    @ApiOperationSupport(order = 8)
    @PostMapping("/status/{id}/{status}")
    @ResponseBody
    public WebResponse<?> status(@PathVariable("id") Long id, @PathVariable("status") Integer status) {
        equipmentInfoExtraService.updateEquipmentStatus(id, status);
        return WebResponse.success();
    }


    @ApiOperation("设备编号获取")
    @ApiImplicitParam(name = "code", value = "设备编号code", required = true, paramType = "path")
    @ApiOperationSupport(order = 7)
    @PostMapping("/create-equipment-code-rule")
    @ResponseBody
    public WebResponse<EquipmentInfoVO> createEquipmentCodeByRule(@RequestBody @Validated EquipmentCodeGenerateVO equipmentCodeGenerate) {
        EquipmentInfoVO equipment = equipmentInfoExtraService.createEquipmentTemp(equipmentCodeGenerate);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE, equipment);
    }


    /**
     * 设备分页查询操作
     *
     * @param equipmentInfoQueryPageParamVO
     * @return
     */
    @ApiOperation("设备查询网关设备")
    @ApiImplicitParam(name = "equipmentInfoQueryPageParamVO", value = "设备分页查询VO对象", required = true, paramType = "query", dataType = "EquipmentInfoQueryPageParamVO")
    @ApiOperationSupport(order = 19)
    @PostMapping("/queryPageGateway")
    @ResponseBody
    public WebResponse<PageData<EquipmentInfoVO>> queryPage4Gateway(@RequestBody EquipmentInfoQueryPageParamVO equipmentInfoQueryPageParamVO) {
        PageData<EquipmentInfoVO> equipmentInfoVOPageData = equipmentInfoExtraService.queryPage(equipmentInfoQueryPageParamVO);
        return WebResponse.success(equipmentInfoVOPageData);
    }


    /**
     * 正常新增设备
     *
     * @param equipmentNormalFormVO 设备基础数据
     * @return
     */
    @ApiOperation("正常新增设备")
    @ApiImplicitParam(name = "equipmentNormalFormVO", value = "设备添加VO对象", required = true, paramType = "query", dataType = "EquipmentInfoVO")
    @ApiOperationSupport(order = 8)
    @PostMapping("/save-equipment-normal")
    @ResponseBody
    public WebResponse<?> saveEquipment4Normal(@RequestBody @Validated EquipmentNormalFormVO equipmentNormalFormVO) {
        equipmentInfoExtraService.saveEquipment4Normal(equipmentNormalFormVO);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }

    /**
     * 模型新增设备
     *
     * @param equipmentModelFormVO 设备基础数据
     * @return
     */
    @ApiOperation("模型新增设备")
    @ApiImplicitParam(name = "equipmentModelFormVO", value = "设备添加VO对象", required = true, paramType = "query", dataType = "EquipmentInfoVO")
    @ApiOperationSupport(order = 8)
    @PostMapping("/save-equipment-model")
    @ResponseBody
    public WebResponse<?> saveEquipment4Model(@RequestBody @Validated EquipmentModelFormVO equipmentModelFormVO) {
        equipmentInfoExtraService.saveEquipment4Model(equipmentModelFormVO);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }

    /**
     * 复制设备 返回id
     *
     * @return
     */
    @ApiOperation("复制设备")
    @ApiImplicitParam(name = "copyId", value = "设备添加VO对象", required = true, paramType = "query", dataType = "Long")
    @ApiOperationSupport(order = 8)
    @PostMapping("/copy-equipment/{copyId}")
    @ResponseBody
    public WebResponse<EquipmentInfoVO> copyEquipment(@PathVariable("copyId") Long copyId) {
        EquipmentInfoVO equipment = equipmentInfoExtraService.copyEquipment(copyId);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE, equipment);
    }

    /**
     * 设备信息修改操作
     *
     * @param equipmentInfoVO
     * @return
     */
    @ApiOperation("设备信息修改操作")
    @ApiImplicitParam(name = "equipmentInfoVO", value = "设备模型修改VO对象", required = true, paramType = "query", dataType = "EquipmentInfoVO")
    @ApiOperationSupport(order = 9)
    @PostMapping("/update")
    @ResponseBody
    public WebResponse<?> update(@RequestBody EquipmentInfoVO equipmentInfoVO) {
        equipmentInfoExtraService.updateEquipment(equipmentInfoVO);
        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
    }

    @ApiOperation("设备标签分页")
    @ApiImplicitParam(name = "equipmentId", value = "设备ID", required = true,
            paramType = "query", dataType = "long")
    @ApiOperationSupport(order = 10)
    @PostMapping("label/queryPage/{equipmentId}")
    public WebResponse<List<LabelVO>> queryPageLabel(@PathVariable("equipmentId") Long equipmentId) {
        List<LabelVO> equipmentInfoTagVOPageData = equipmentInfoExtraService.listEquipmentLabelByEquipment(equipmentId);
        return WebResponse.success(equipmentInfoTagVOPageData);
    }

//    @ApiOperation("设备标签添加")
//    @ApiImplicitParam(name = "equipmentId", value = "设备ID", required = true,
//            paramType = "query", dataType = "long")
//    @ApiOperationSupport(order = 11)
//    @PostMapping("/label/save/{equipmentId}")
//    public WebResponse<?> saveLabel(@PathVariable("equipmentId") Long equipmentId, @RequestBody List<LabelVO> labelList) {
//        equipmentInfoExtraService.saveEquipmentLabelList(equipmentId, labelList);
//        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
//    }

//    @ApiOperation("设备标签删除")
//    @ApiImplicitParam(name = "id", value = "设备标签ID", required = true,
//            paramType = "path", dataType = "long")
//    @ApiOperationSupport(order = 12)
//    @GetMapping("/label/delete/{equipmentId}/{labelItemId}")
//    public WebResponse<?> deleteLabel(@PathVariable("equipmentId") Long equipmentId, @PathVariable("labelItemId") Long labelItemId) {
//        equipmentInfoExtraService.deleteLabel(equipmentId, labelItemId);
//        return WebResponse.success(ResultConstant.OPERATE_SUCCESS_MESSAGE);
//    }


    @PostMapping("/export-template/{type}")
    @ApiOperation(value = "普通导入-获取导入模板")
    public void exportTemplate(@PathVariable("type") String type, HttpServletResponse response) {
        EasyExcelUtils.exportExcelManySheet(response, "设备导入模版",BeanUtils.copyToList( ExcelSheetUtil.buildEquipmentSheetList(), ExcelSheetVO.class));
    }

    @PostMapping("/import/{type}")
    @ApiOperation(value = "普通导入-导入设备")
    public WebResponse<?> importExcel(@PathVariable("type") String type, @RequestParam("file") MultipartFile file) {
        List<ExcelSheetVO> excelSheetList = BeanUtils.copyToList( ExcelSheetUtil.buildEquipmentSheetList(), ExcelSheetVO.class);
        Map<Class<?>, List<?>> map = null;
        try {
            map = EasyExcelUtils.importExcelManySheet(file, excelSheetList);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        DataParamImportEnum importEnum = "meter".equals(type) ? DataParamImportEnum.METER_EQUIPMENT : DataParamImportEnum.EQUIPMENT;
        ExcelResultVO excelResult = importExcelService.importEquipmentExcel(importEnum, map, excelSheetList);
        return excelResult.getWebResponse();
    }

    @PostMapping("/export/{type}")
    @ApiOperation(value = "普通导出-导出设备")
    public void export(@PathVariable("type") String type,
                       HttpServletResponse response,
                       @RequestBody EquipmentInfoQueryPageParamVO equipmentInfoQueryPageParamVO) {
        equipmentInfoQueryPageParamVO.setPageNo(0);
        equipmentInfoQueryPageParamVO.setPageSize(Integer.MAX_VALUE);
        PageData<EquipmentInfoVO> result = equipmentInfoExtraService.queryPage(equipmentInfoQueryPageParamVO);
        Collection<EquipmentInfoVO> data = result.getData();
        EasyExcelUtils.exportExcel(response, "设备导出", BeanUtils.copyToList(data, ExportExcelEquipmentVO.class), ExportExcelEquipmentVO.class);
    }

    @PostMapping("/export-template-model/{type}")
    @ApiOperation(value = "模型导入-获取导入模板")
    public void exportTemplateModel(@PathVariable("type") String type, HttpServletResponse response) {
        EasyExcelUtils.exportExcelManySheet(response, "设备导入模版", BeanUtils.copyToList( ExcelSheetUtil.buildEquipmentSheetList(), ExcelSheetVO.class));
    }


    @PostMapping("/import-model/{type}")
    @ApiOperation(value = "模型导入-导入模板")
    public WebResponse<?> importModelExcel(@PathVariable("type") String type, @RequestParam("file") MultipartFile file) {
        List<ExcelSheetVO> excelSheetList = BeanUtils.copyToList( ExcelSheetUtil.buildEquipmentSheetList(), ExcelSheetVO.class);
        Map<Class<?>, List<?>> map = null;
        try {
            map = EasyExcelUtils.importExcelManySheet(file, excelSheetList);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        DataParamImportEnum importEnum = "meter".equals(type) ? DataParamImportEnum.METER_EQUIPMENT : DataParamImportEnum.EQUIPMENT;
        ExcelResultVO excelResult = importExcelService.importEquipmentModelExcel(importEnum, map, excelSheetList);
        return excelResult.getWebResponse();
    }

}
